
package com.neo.tiny.oauth.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.neo.tiny.common.constant.ErrorCodeConstants;
import com.neo.tiny.common.exception.WebApiException;
import com.neo.tiny.oauth.entity.SysOauth2CodeDO;
import com.neo.tiny.oauth.mapper.SysOauth2CodeMapper;
import com.neo.tiny.oauth.service.SysOauth2CodeService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @Description: OAuth2 授权码
 * @Author: yqz
 * @CreateDate: 2022-11-11 10:44:38
 */
@Service
@AllArgsConstructor
public class SysOauth2CodeServiceImpl extends ServiceImpl<SysOauth2CodeMapper, SysOauth2CodeDO> implements SysOauth2CodeService {

    /**
     * 授权码的过期时间，默认 5 分钟
     */
    private static final Integer TIMEOUT = 5 * 60;

    private final SysOauth2CodeMapper oauth2CodeMapper;

    @Override
    public SysOauth2CodeDO consumeAuthorizationCode(String code) {

        SysOauth2CodeDO codeDO = oauth2CodeMapper.selectByCode(code);
        if (Objects.isNull(codeDO)) {
            throw new WebApiException(ErrorCodeConstants.OAUTH2_CODE_NOT_EXISTS);
        }

        if (codeDO.getExpiresTime().isBefore(LocalDateTime.now())) {
            throw new WebApiException(ErrorCodeConstants.OAUTH2_CODE_EXPIRE);
        }
        oauth2CodeMapper.deleteById(codeDO.getId());
        return codeDO;
    }

    @Override
    public SysOauth2CodeDO createAuthorizationCode(Long userId, String userName, Integer userType,
                                                   String clientId, List<String> scopes,
                                                   String redirectUri, String state) {

        SysOauth2CodeDO codeDO = new SysOauth2CodeDO();
        codeDO.setCode(generateCode());
        codeDO.setUserId(userId);
        codeDO.setUserName(userName);
        codeDO.setUserType(userType);
        codeDO.setClientId(clientId);
        codeDO.setScopes(scopes);
        codeDO.setExpiresTime(LocalDateTime.now().plusSeconds(TIMEOUT));
        codeDO.setRedirectUri(redirectUri);
        codeDO.setState(state);

        oauth2CodeMapper.insert(codeDO);
        return codeDO;
    }

    private static String generateCode() {
        return IdUtil.fastSimpleUUID();
    }
}
